package cn.com.acca.ma.service.impl;

import cn.com.acca.ma.common.util.DateUtil;
import cn.com.acca.ma.common.util.HttpClientUtil;
import cn.com.acca.ma.common.util.ModelConverter;
import cn.com.acca.ma.common.util.PropertiesUtil;
import cn.com.acca.ma.constant.FilterMethod;
import cn.com.acca.ma.constant.ShippingSpaceControlInRealTransaction;
import cn.com.acca.ma.constant.StockInfoMark;
import cn.com.acca.ma.model.*;
import cn.com.acca.ma.pojo.*;
import cn.com.acca.ma.service.Real3StockTransactionRecordService;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class Real3StockTransactionRecordServiceImpl extends BaseServiceImpl<Real3StockTransactionRecordServiceImpl, Real3StockTransactionRecord> implements
        Real3StockTransactionRecordService {

    /**
     * 实时地判断买卖条件，给出交易建议，并保存在文件中
     */
    @Override
    public void realTimeJudgeConditionAndGiveSuggestion() {
        logger.info("开始实时地判断买卖条件，给出交易建议，并保存在文件中");

        // 买卖建议字符串
        StringBuffer printRealBuySellSuggestion = new StringBuffer();

        // 参数
        String date = PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.real3.transaction.realtime.judge.condition.give.suggestion.date");
        boolean historyDataJudge = Boolean.parseBoolean(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.real3.transaction.history.data.judge.condition.give.suggestion"));
//        Integer backwardMonth = Integer.parseInt(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.real3.transaction.stock.success.rate.backward.month"));
//        Integer averageDateNumber = Integer.parseInt(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.real3.transaction.success.rate.average.date.number"));
//        Double macdMultiplicationFactor = Double.parseDouble(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.real3.transaction.success.rate.average.date.macd.multiplication.factor"));
//        Double closePriceMa5MultiplicationFactor = Double.parseDouble(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.real3.transaction.success.rate.average.date.closePriceMa5.multiplication.factor"));
//        Double heiKinAshiMultiplicationFactor = Double.parseDouble(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.real3.transaction.success.rate.average.date.heiKinAshi.multiplication.factor"));
//        Double kdMultiplicationFactor = Double.parseDouble(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.real3.transaction.success.rate.average.date.kd.multiplication.factor"));
//        Integer transactionStrategy = Integer.parseInt(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.real3.transaction.strategy"));
//        Double threshold = Double.parseDouble(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.real3.transaction.strategy.success.rate.threshold"));
        String xrBeginDate = PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.real3.transaction.xr.begin.date");
        String highestLowestPriceBeginDate = PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.real3.transaction.current.closePrice.compareTo.someTime.highest.lowest.price.begin.date");
        Integer currentClosePriceCompareToSomeTimeHighestPrice = Integer.parseInt(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.real3.transaction.current.closePrice.compareTo.someTime.highest.price"));
        Integer currentClosePriceCompareToSomeTimeLowestPrice = Integer.parseInt(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.real3.transaction.current.closePrice.compareTo.someTime.lowest.price"));
        Integer closePriceStart = Integer.parseInt(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.real3.transaction.closePrice.start"));
        Integer closePriceEnd = Integer.parseInt(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.real3.transaction.closePrice.end"));
        Integer oneStockTransactionCapitalAmount = Integer.parseInt(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.real3.transaction.one.stock.transaction.capital.amount"));
        Boolean useMinFilterConditionWhenBuy = Boolean.parseBoolean(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.real3.transaction.useMinFilterConditionWhenBuy"));
        Boolean useMinFilterConditionWhenSell = Boolean.parseBoolean(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.real3.transaction.useMinFilterConditionWhenSell"));
//        Integer shippingSpaceControl = Integer.parseInt(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.real3.transaction.shippingSpaceControl"));
        Integer shippingSpace = Integer.parseInt(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.real3.transaction.shippingSpace"));

        BullStockSuggestionList bullStockSuggestionList = new BullStockSuggestionList();
        ShortStockSuggestionList shortStockSuggestionList = new ShortStockSuggestionList();
        /*********************************** 卖股票/还券的建议 *********************************/
        // 查找real3_stock_transaction_record表中，sell_date、sell_price、sell_amount列都为空的记录
        List<StockInfoPojo> shouldSellBullStockList = new ArrayList<>();
        List<Real3StockTransactionRecord> holdBullStockNumberList = real3StockTransactionRecordDao.findBySellDateNullAndSellPriceNullAndSellAmountNull();
        for (int i = 0; i < holdBullStockNumberList.size(); i++) {
            Real3StockTransactionRecord real3StockTransactionRecord = holdBullStockNumberList.get(i);
            StockInfo stockInfo = stockInfoDao.getStockInfoObjectByStockCode(real3StockTransactionRecord.getStockCode());

            // 开盘价，最新价，最高价，最低价
            BigDecimal newestOpenPrice = null;
            BigDecimal newestClosePrice = null;
            BigDecimal newestHighestPrice = null;
            BigDecimal newestLowestPrice = null;
            if (!historyDataJudge) {
                // 像股票代码为510300（ETF300）这种股票在stock_info表中没有，此处只能continue
                if (null == stockInfo) {
                    logger.warn("股票【" + real3StockTransactionRecord.getStockCode() + "】在表stock_info中没有记录");
                    continue;
                }
                String content = null;
                try {
                    content = HttpClientUtil.get(HQ_SINAJS_URL_PREFIX + stockInfo.getUrlParam());
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (URISyntaxException e) {
                    e.printStackTrace();
                }
                JSONObject jsonObject = JSONObject.parseObject(content);
                JSONArray jsonArray = jsonObject.getJSONArray("data");
                JSONObject param = jsonArray.getJSONObject(0);
                newestOpenPrice = new BigDecimal(param.getDouble("open"));
                newestClosePrice = new BigDecimal(param.getDouble("current"));
                newestHighestPrice = new BigDecimal(param.getDouble("high"));
                newestLowestPrice = new BigDecimal(param.getDouble("low"));
            } else {
                if (real3StockTransactionRecord.getStockCode().equals("600757")) {
                    int x = 0;
                }

                StockTransactionDataAll tempStockTransactionDataAll = stockTransactionDataDao.findByCodeAndDate(stockInfo.getUrlParam().substring(2), DateUtil.stringToDate(date));
                if (null == tempStockTransactionDataAll) {
                    logger.warn("股票【" + stockInfo.getCode() + "】，日期【" + date + "】在表stock_transaction_data_all中没有记录");
                    continue;
                }
                newestOpenPrice = tempStockTransactionDataAll.getOpenPrice();
                newestClosePrice = tempStockTransactionDataAll.getClosePrice();
                newestHighestPrice = tempStockTransactionDataAll.getHighestPrice();
                newestLowestPrice = tempStockTransactionDataAll.getLowestPrice();
            }

            Real3TransactionCondition real3TransactionCondition = real3TransactionConditionDao.findByStockCode(real3StockTransactionRecord.getStockCode());

            // 判断是否满足卖出条件
        }
        bullStockSuggestionList.setShouldSellBullStockList(shouldSellBullStockList);
        // 查找real_stock_transaction_record表中，buy_date、buy_price、buy_amount列都为空的记录
        List<StockInfoPojo> shouldBuyShortStockList = new ArrayList<>();
        List<RealStockTransactionRecord> holdShortStockNumberList = realStockTransactionRecordDao.findByBuyDateNullAndBuyPriceNullAndBuyAmountNull();
        for (int i = 0; i < holdShortStockNumberList.size(); i++) {
            RealStockTransactionRecord realStockTransactionRecord = holdShortStockNumberList.get(i);
            StockInfo stockInfo = stockInfoDao.getStockInfoObjectByStockCode(realStockTransactionRecord.getStockCode());

            // 开盘价，最新价，最高价，最低价
            BigDecimal newestOpenPrice = null;
            BigDecimal newestClosePrice = null;
            BigDecimal newestHighestPrice = null;
            BigDecimal newestLowestPrice = null;
            if (!historyDataJudge) {
                // 像股票代码为510300（ETF300）这种股票在stock_info表中没有，此处只能continue
                if (null == stockInfo) {
                    logger.warn("股票【" + realStockTransactionRecord.getStockCode() + "】在表stock_info中没有记录");
                    continue;
                }
                String content = null;
                try {
                    content = HttpClientUtil.get(HQ_SINAJS_URL_PREFIX + stockInfo.getUrlParam());
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (URISyntaxException e) {
                    e.printStackTrace();
                }
                JSONObject jsonObject = JSONObject.parseObject(content);
                JSONArray jsonArray = jsonObject.getJSONArray("data");
                JSONObject param = jsonArray.getJSONObject(0);
                newestOpenPrice = new BigDecimal(param.getDouble("open"));
                newestClosePrice = new BigDecimal(param.getDouble("current"));
                newestHighestPrice = new BigDecimal(param.getDouble("high"));
                newestLowestPrice = new BigDecimal(param.getDouble("low"));
            } else {
                if (realStockTransactionRecord.getStockCode().equals("600757")) {
                    int x = 0;
                }

                StockTransactionDataAll tempStockTransactionDataAll = stockTransactionDataDao.findByCodeAndDate(stockInfo.getUrlParam().substring(2), DateUtil.stringToDate(date));
                if (null == tempStockTransactionDataAll) {
                    logger.warn("股票【" + stockInfo.getCode() + "】，日期【" + date + "】在表stock_transaction_data_all中没有记录");
                    continue;
                }
                newestOpenPrice = tempStockTransactionDataAll.getOpenPrice();
                newestClosePrice = tempStockTransactionDataAll.getClosePrice();
                newestHighestPrice = tempStockTransactionDataAll.getHighestPrice();
                newestLowestPrice = tempStockTransactionDataAll.getLowestPrice();
            }

            RealTransactionCondition realTransactionCondition = realTransactionConditionDao.findByStockCode(realStockTransactionRecord.getStockCode());

            // 判断是否满足还券条件

        }
        shortStockSuggestionList.setShouldBuyShortStockList(shouldBuyShortStockList);

        /*********************************** 买股票/融券的建议 *********************************/
        List<StockInfoPojo> shouldBuyBullStockList = new ArrayList<>();
        List<StockInfoPojo> shouldSellShortStockList = new ArrayList<>();
        List<StockInfoPojo> macdGoldCrossShouldBuyStockList = new ArrayList<>();
        List<StockInfoPojo> macdDeadCrossShouldSellStockList = new ArrayList<>();
        List<StockInfoPojo> closePriceGoldCrossMa5ShouldBuyStockList = new ArrayList<>();
        List<StockInfoPojo> closePriceDeadCrossMa5ShouldSellStockList = new ArrayList<>();
        List<StockInfoPojo> heiKinAshiUpDownShouldBuyStockList = new ArrayList<>();
        List<StockInfoPojo> heiKinAshiDownUpShouldSellStockList = new ArrayList<>();
        List<StockInfoPojo> kdGoldCrossShouldBuyStockList = new ArrayList<>();
        List<StockInfoPojo> kdDeadCrossShouldSellStockList = new ArrayList<>();
        if (null != FilterMethod.SELECT_FILTER_METHOD) {
            // 判断做多/做空时，是使用所有过滤条件，还是使用最少的过滤条件
            boolean allFilterCondition = true;
            if (useMinFilterConditionWhenSell) {
                allFilterCondition = false;
            }
            if (useMinFilterConditionWhenBuy) {
                allFilterCondition = false;
            }
            List<RealTransactionCondition> realTransactionConditionList = realTransactionConditionDao.findByCondition(allFilterCondition);
            if (null != realTransactionConditionList && realTransactionConditionList.size() > 0) {
                for (int i = 0; i < realTransactionConditionList.size(); i++) {
                    RealTransactionCondition realTransactionCondition = realTransactionConditionList.get(i);
                    StockInfo stockInfo = stockInfoDao.getStockInfoObjectByStockCode(realTransactionCondition.getStockCode());

                    // 开盘价，最新价，最高价，最低价
                    BigDecimal newestOpenPrice = null;
                    BigDecimal newestClosePrice = null;
                    BigDecimal newestHighestPrice = null;
                    BigDecimal newestLowestPrice = null;
                    if (!historyDataJudge) {
                        // 像股票代码为510300（ETF300）这种股票在stock_info表中没有，此处只能continue
                        if (null == stockInfo) {
                            logger.warn("股票【" + stockInfo.getCode() + "】在表stock_info中没有记录");
                            continue;
                        }
                        String content = null;
                        try {
                            content = HttpClientUtil.get(HQ_SINAJS_URL_PREFIX + stockInfo.getUrlParam());
                        } catch (MalformedURLException e) {
                            e.printStackTrace();
                        } catch (URISyntaxException e) {
                            e.printStackTrace();
                        }
                        JSONObject jsonObject = JSONObject.parseObject(content);
                        JSONArray jsonArray = jsonObject.getJSONArray("data");
                        JSONObject param = jsonArray.getJSONObject(0);
                        newestOpenPrice = new BigDecimal(param.getDouble("open"));
                        newestClosePrice = new BigDecimal(param.getDouble("current"));
                        newestHighestPrice = new BigDecimal(param.getDouble("high"));
                        newestLowestPrice = new BigDecimal(param.getDouble("low"));
                    } else {
                        if (stockInfo.getCode().equals("600757")) {
                            int x = 0;
                        }

                        StockTransactionDataAll tempStockTransactionDataAll = stockTransactionDataDao.findByCodeAndDate(stockInfo.getUrlParam().substring(2), DateUtil.stringToDate(date));
                        if (null == tempStockTransactionDataAll) {
                            logger.warn("股票【" + stockInfo.getCode() + "】，日期【" + date + "】在表stock_transaction_data_all中没有记录");
                            continue;
                        }
                        newestOpenPrice = tempStockTransactionDataAll.getOpenPrice();
                        newestClosePrice = tempStockTransactionDataAll.getClosePrice();
                        newestHighestPrice = tempStockTransactionDataAll.getHighestPrice();
                        newestLowestPrice = tempStockTransactionDataAll.getLowestPrice();
                    }

                    if (FilterMethod.SELECT_FILTER_METHOD % 2 == 1) {
                        // 如果当前价格/某段时间的最高收盘价>参数currentClosePriceCompareToSomeTimeHighestPrice，则跳过
                        BigDecimal maxHighestPrice = stockTransactionDataDao.findMaxHighestPriceBetweenDate(realTransactionCondition.getStockCode(), highestLowestPriceBeginDate, date);
//                        BigDecimal b1 = newestClosePrice.divide(maxClosePrice, 2, BigDecimal.ROUND_HALF_UP);
//                        double d1 = b1.doubleValue();
                        if (newestClosePrice.divide(maxHighestPrice, 4, BigDecimal.ROUND_HALF_UP).doubleValue() * 100 > currentClosePriceCompareToSomeTimeHighestPrice.doubleValue()) {
                            continue;
                        }
                    } else {
                        // 如果当前价格/某段时间的最低收盘价<参数currentClosePriceCompareToSomeTimeLowestPrice，则跳过
                        BigDecimal minLowestPrice = stockTransactionDataDao.findMinLowestPriceBetweenDate(realTransactionCondition.getStockCode(), highestLowestPriceBeginDate, date);
                        if (newestClosePrice.divide(minLowestPrice, 4, BigDecimal.ROUND_HALF_UP).doubleValue() * 100 < currentClosePriceCompareToSomeTimeLowestPrice.doubleValue()) {
                            continue;
                        }
                    }

                    // 如果当前价格不在区间之内，则跳过
                    if (newestClosePrice.doubleValue() < closePriceStart || newestClosePrice.doubleValue() > closePriceEnd) {
                        continue;
                    }

                    // 如果这只股票当日除权了，则跳过
                    BigDecimal previousClosePrice = stockTransactionDataDao.findLastClosePriceByCodeAndDate(false, realTransactionCondition.getStockCode(), date);
                    double downPercentage = newestClosePrice.subtract(previousClosePrice).divide(previousClosePrice, 2, BigDecimal.ROUND_HALF_UP).doubleValue() * 100;
                    Date judgementDate = DateUtil.stringToDate("2020-08-24");
                    if (DateUtil.stringToDate(xrBeginDate).before(judgementDate)
                            && downPercentage < -11) {
                        continue;
                    }
                    if ((DateUtil.stringToDate(xrBeginDate).after(judgementDate) || DateUtil.stringToDate(xrBeginDate).equals(judgementDate))
                            && stockInfo.getCode().startsWith("300")
                            && downPercentage < -22) {
                        continue;
                    }
                    if ((DateUtil.stringToDate(xrBeginDate).after(judgementDate) || DateUtil.stringToDate(xrBeginDate).equals(judgementDate))
                            && !stockInfo.getCode().startsWith("300")
                            && downPercentage < -11) {
                        continue;
                    }

                    if (FilterMethod.SELECT_FILTER_METHOD % 2 == 1) {
                        // 如果这只股票不是ma120单调不递减，则跳过（除了计算之前那些天-1的，还要计算当前日期的）
//                        if (!stockTransactionDataDao.ma120NotDecreasing(realTransactionCondition.getStockCode(), newestClosePrice, date)){
                        if (!realTransactionCondition.getIsMa120NotDecreasing().equals(1)
                                || !stockTransactionDataDao.isMa120NotDecreasing(realTransactionCondition.getStockCode(), newestClosePrice, date)) {
                            continue;
                        }
                        // 如果这只股票不是ma250单调不递减，则跳过（除了计算之前那些天-1的，还要计算当前日期的）
//                        if (!stockTransactionDataDao.ma250NotDecreasing(realTransactionCondition.getStockCode(), newestClosePrice, date)){
                        if (!realTransactionCondition.getIsMa250NotDecreasing().equals(1)
                                || !stockTransactionDataDao.isMa250NotDecreasing(realTransactionCondition.getStockCode(), newestClosePrice, date)) {
                            continue;
                        }
                    } else {
                        // 如果这只股票不是ma120单调不递增，则跳过（除了计算之前那些天-1的，还要计算当前日期的）
//                        if (!stockTransactionDataDao.ma120NotIncreasing(realTransactionCondition.getStockCode(), newestClosePrice, date)){
                        if (!realTransactionCondition.getIsMa120NotIncreasing().equals(1)
                                || !stockTransactionDataDao.isMa120NotIncreasing(realTransactionCondition.getStockCode(), newestClosePrice, date)) {
                            continue;
                        }
                        // 如果这只股票不是ma250单调不递增，则跳过（除了计算之前那些天-1的，还要计算当前日期的）
//                        if (!stockTransactionDataDao.ma250NotIncreasing(realTransactionCondition.getStockCode(), newestClosePrice, date)){
                        if (!realTransactionCondition.getIsMa250NotIncreasing().equals(1)
                                || !stockTransactionDataDao.isMa250NotIncreasing(realTransactionCondition.getStockCode(), newestClosePrice, date)) {
                            continue;
                        }
                    }

                    // 要计算的是前一天的数据
                    String lastDate = DateUtil.dateToString(stockTransactionDataDao.findPreviousDateByDate(false, date));
                    StockTransactionData stockTransactionData = stockTransactionDataDao.findLastByCodeAndDate(stockInfo.getCode(), DateUtil.stringToDate(lastDate));
                    // macd金叉
                    if (null != realTransactionCondition
                            && null != realTransactionCondition.getMacdGoldCrossClosePrice()
                            && FilterMethod.SELECT_FILTER_METHOD == FilterMethod.MACD_GOLD_CROSS
                            && newestClosePrice.compareTo(realTransactionCondition.getMacdGoldCrossClosePrice()) >= 0) {
                        StockInfoPojo stockInfoPojo = ModelConverter.stockInfoToStockInfoPojo(stockInfo);
                        stockInfoPojo.setAmount(((int) (oneStockTransactionCapitalAmount.intValue() / newestClosePrice.doubleValue()) / 100 * 100));
                        shouldBuyBullStockList.add(stockInfoPojo);
                    }
                    if (null != realTransactionCondition
                            && null != realTransactionCondition.getMacdGoldCrossClosePrice()
                            && FilterMethod.SELECT_FILTER_METHOD != FilterMethod.MACD_GOLD_CROSS
                            && newestClosePrice.compareTo(realTransactionCondition.getMacdGoldCrossClosePrice()) >= 0) {
                        StockInfoPojo stockInfoPojo = ModelConverter.stockInfoToStockInfoPojo(stockInfo);
                        stockInfoPojo.setAmount(((int) (oneStockTransactionCapitalAmount.intValue() / newestClosePrice.doubleValue()) / 100 * 100));
                        macdGoldCrossShouldBuyStockList.add(stockInfoPojo);
                    }
                    // macd死叉
                    if (null != realTransactionCondition
                            && null != realTransactionCondition.getMacdDeadCrossClosePrice()
                            && FilterMethod.SELECT_FILTER_METHOD == FilterMethod.MACD_DEAD_CROSS
                            && newestClosePrice.compareTo(realTransactionCondition.getMacdDeadCrossClosePrice()) <= 0
                            && null != stockInfo.getMark()
                            && stockInfo.getMark().equals(StockInfoMark.SECURITIES_LENDING)) {
                        StockInfoPojo stockInfoPojo = ModelConverter.stockInfoToStockInfoPojo(stockInfo);
                        stockInfoPojo.setAmount(((int) (oneStockTransactionCapitalAmount.intValue() / newestClosePrice.doubleValue()) / 100 * 100));
                        shouldSellShortStockList.add(stockInfoPojo);
                    }
                    if (null != realTransactionCondition
                            && null != realTransactionCondition.getMacdDeadCrossClosePrice()
                            && FilterMethod.SELECT_FILTER_METHOD != FilterMethod.MACD_DEAD_CROSS
                            && newestClosePrice.compareTo(realTransactionCondition.getMacdDeadCrossClosePrice()) <= 0
                            && null != stockInfo.getMark()
                            && stockInfo.getMark().equals(StockInfoMark.SECURITIES_LENDING)) {
                        StockInfoPojo stockInfoPojo = ModelConverter.stockInfoToStockInfoPojo(stockInfo);
                        stockInfoPojo.setAmount(((int) (oneStockTransactionCapitalAmount.intValue() / newestClosePrice.doubleValue()) / 100 * 100));
                        macdDeadCrossShouldSellStockList.add(stockInfoPojo);
                    }
                    // close_price金叉ma5
                    if (null != realTransactionCondition
                            && null != realTransactionCondition.getCPMa5GCClosePrice()
                            && FilterMethod.SELECT_FILTER_METHOD == FilterMethod.CLOSE_PRICE_GOLD_CROSS_MA
                            && newestClosePrice.compareTo(realTransactionCondition.getCPMa5GCClosePrice().multiply(new BigDecimal(4)).add(newestClosePrice).divide(new BigDecimal(5), 2, BigDecimal.ROUND_HALF_UP)) >= 0) {
                        StockInfoPojo stockInfoPojo = ModelConverter.stockInfoToStockInfoPojo(stockInfo);
                        stockInfoPojo.setAmount(((int) (oneStockTransactionCapitalAmount.intValue() / newestClosePrice.doubleValue()) / 100 * 100));
                        shouldBuyBullStockList.add(stockInfoPojo);
                    }
                    if (null != realTransactionCondition
                            && null != realTransactionCondition.getCPMa5GCClosePrice()
                            && FilterMethod.SELECT_FILTER_METHOD != FilterMethod.CLOSE_PRICE_GOLD_CROSS_MA
                            && newestClosePrice.compareTo(realTransactionCondition.getCPMa5GCClosePrice().multiply(new BigDecimal(4)).add(newestClosePrice).divide(new BigDecimal(5), 2, BigDecimal.ROUND_HALF_UP)) >= 0) {
                        StockInfoPojo stockInfoPojo = ModelConverter.stockInfoToStockInfoPojo(stockInfo);
                        stockInfoPojo.setAmount(((int) (oneStockTransactionCapitalAmount.intValue() / newestClosePrice.doubleValue()) / 100 * 100));
                        closePriceGoldCrossMa5ShouldBuyStockList.add(stockInfoPojo);
                    }
                    // close_price死叉ma5
                    if (null != realTransactionCondition
                            && null != realTransactionCondition.getCPMa5DCClosePrice()
                            && FilterMethod.SELECT_FILTER_METHOD == FilterMethod.CLOSE_PRICE_DEAD_CROSS_MA
                            && newestClosePrice.compareTo(realTransactionCondition.getCPMa5DCClosePrice().multiply(new BigDecimal(4)).add(newestClosePrice).divide(new BigDecimal(5), 2, BigDecimal.ROUND_HALF_UP)) <= 0
                            && null != stockInfo.getMark()
                            && stockInfo.getMark().equals(StockInfoMark.SECURITIES_LENDING)) {
                        StockInfoPojo stockInfoPojo = ModelConverter.stockInfoToStockInfoPojo(stockInfo);
                        stockInfoPojo.setAmount(((int) (oneStockTransactionCapitalAmount.intValue() / newestClosePrice.doubleValue()) / 100 * 100));
                        shouldSellShortStockList.add(stockInfoPojo);
                    }
                    if (null != realTransactionCondition
                            && null != realTransactionCondition.getCPMa5DCClosePrice()
                            && FilterMethod.SELECT_FILTER_METHOD != FilterMethod.CLOSE_PRICE_DEAD_CROSS_MA
                            && newestClosePrice.compareTo(realTransactionCondition.getCPMa5DCClosePrice().multiply(new BigDecimal(4)).add(newestClosePrice).divide(new BigDecimal(5), 2, BigDecimal.ROUND_HALF_UP)) <= 0
                            && null != stockInfo.getMark()
                            && stockInfo.getMark().equals(StockInfoMark.SECURITIES_LENDING)) {
                        StockInfoPojo stockInfoPojo = ModelConverter.stockInfoToStockInfoPojo(stockInfo);
                        stockInfoPojo.setAmount(((int) (oneStockTransactionCapitalAmount.intValue() / newestClosePrice.doubleValue()) / 100 * 100));
                        closePriceDeadCrossMa5ShouldSellStockList.add(stockInfoPojo);
                    }
                    // hei_kin_ashi上涨趋势
                    if (null != realTransactionCondition
                            && null != realTransactionCondition.getHKAUpHKAOpenPrice()
                            && FilterMethod.SELECT_FILTER_METHOD == FilterMethod.HEI_KIN_ASHI_UP_DOWN) {
                        BigDecimal heiKinAshiClosePrice = newestOpenPrice.add(newestClosePrice).add(newestHighestPrice).add(newestLowestPrice).divide(new BigDecimal(4), 2, BigDecimal.ROUND_HALF_UP);
                        BigDecimal heiKinAshiOpenPrice = stockTransactionData.getHaOpenPrice().add(stockTransactionData.getHaClosePrice()).divide(new BigDecimal(2), 2, BigDecimal.ROUND_HALF_UP);
                        if (heiKinAshiClosePrice.compareTo(heiKinAshiOpenPrice) > 0) {
                            StockInfoPojo stockInfoPojo = ModelConverter.stockInfoToStockInfoPojo(stockInfo);
                            stockInfoPojo.setAmount(((int) (oneStockTransactionCapitalAmount.intValue() / newestClosePrice.doubleValue()) / 100 * 100));
                            shouldBuyBullStockList.add(stockInfoPojo);
                        }
                    }
                    if (null != realTransactionCondition
                            && null != realTransactionCondition.getHKAUpHKAOpenPrice()
                            && FilterMethod.SELECT_FILTER_METHOD != FilterMethod.HEI_KIN_ASHI_UP_DOWN) {
                        BigDecimal heiKinAshiClosePrice = newestOpenPrice.add(newestClosePrice).add(newestHighestPrice).add(newestLowestPrice).divide(new BigDecimal(4), 2, BigDecimal.ROUND_HALF_UP);
                        BigDecimal heiKinAshiOpenPrice = stockTransactionData.getHaOpenPrice().add(stockTransactionData.getHaClosePrice()).divide(new BigDecimal(2), 2, BigDecimal.ROUND_HALF_UP);
                        if (heiKinAshiClosePrice.compareTo(heiKinAshiOpenPrice) > 0) {
                            StockInfoPojo stockInfoPojo = ModelConverter.stockInfoToStockInfoPojo(stockInfo);
                            stockInfoPojo.setAmount(((int) (oneStockTransactionCapitalAmount.intValue() / newestClosePrice.doubleValue()) / 100 * 100));
                            heiKinAshiUpDownShouldBuyStockList.add(stockInfoPojo);
                        }
                    }
                    // hei_kin_ashi下跌趋势
                    if (null != realTransactionCondition
                            && null != realTransactionCondition.getHKADownHKAOpenPrice()
                            && FilterMethod.SELECT_FILTER_METHOD == FilterMethod.HEI_KIN_ASHI_DOWN_UP
                            && null != stockInfo.getMark()
                            && stockInfo.getMark().equals(StockInfoMark.SECURITIES_LENDING)) {
                        BigDecimal heiKinAshiClosePrice = newestOpenPrice.add(newestClosePrice).add(newestHighestPrice).add(newestLowestPrice).divide(new BigDecimal(4), 2, BigDecimal.ROUND_HALF_UP);
//                        BigDecimal heiKinAshiClosePrice = newestOpenPrice.add(newestClosePrice).add(newestHighestPrice).add(newestLowestPrice).divide(new BigDecimal(4));
                        BigDecimal heiKinAshiOpenPrice = stockTransactionData.getHaOpenPrice().add(stockTransactionData.getHaClosePrice()).divide(new BigDecimal(2), 2, BigDecimal.ROUND_HALF_UP);
//                        BigDecimal heiKinAshiOpenPrice = stockTransactionData.getHaOpenPrice().add(stockTransactionData.getClosePrice()).divide(new BigDecimal(2));
                        if (heiKinAshiClosePrice.compareTo(heiKinAshiOpenPrice) < 0) {
                            StockInfoPojo stockInfoPojo = ModelConverter.stockInfoToStockInfoPojo(stockInfo);
                            stockInfoPojo.setAmount(((int) (oneStockTransactionCapitalAmount.intValue() / newestClosePrice.doubleValue()) / 100 * 100));
                            shouldSellShortStockList.add(stockInfoPojo);
                        }
                    }
                    if (null != realTransactionCondition
                            && null != realTransactionCondition.getHKADownHKAOpenPrice()
                            && FilterMethod.SELECT_FILTER_METHOD != FilterMethod.HEI_KIN_ASHI_DOWN_UP
                            && null != stockInfo.getMark()
                            && stockInfo.getMark().equals(StockInfoMark.SECURITIES_LENDING)) {
                        BigDecimal heiKinAshiClosePrice = newestOpenPrice.add(newestClosePrice).add(newestHighestPrice).add(newestLowestPrice).divide(new BigDecimal(4), 2, BigDecimal.ROUND_HALF_UP);
//                        BigDecimal heiKinAshiClosePrice = newestOpenPrice.add(newestClosePrice).add(newestHighestPrice).add(newestLowestPrice).divide(new BigDecimal(4));
                        BigDecimal heiKinAshiOpenPrice = stockTransactionData.getHaOpenPrice().add(stockTransactionData.getHaClosePrice()).divide(new BigDecimal(2), 2, BigDecimal.ROUND_HALF_UP);
//                        BigDecimal heiKinAshiOpenPrice = stockTransactionData.getHaOpenPrice().add(stockTransactionData.getClosePrice()).divide(new BigDecimal(2));
                        if (heiKinAshiClosePrice.compareTo(heiKinAshiOpenPrice) < 0) {
                            StockInfoPojo stockInfoPojo = ModelConverter.stockInfoToStockInfoPojo(stockInfo);
                            stockInfoPojo.setAmount(((int) (oneStockTransactionCapitalAmount.intValue() / newestClosePrice.doubleValue()) / 100 * 100));
                            heiKinAshiDownUpShouldSellStockList.add(stockInfoPojo);
                        }
                    }
                    // kd金叉
                    if (null != realTransactionCondition
                            && null != realTransactionCondition.getKdGoldCrossRsv()
                            && FilterMethod.SELECT_FILTER_METHOD == FilterMethod.KD_GOLD_CROSS) {
                        Object object = stockTransactionDataDao.findHighestAndLowestClosePriceByCodeAndDateInEightDay(stockInfo.getCode(), DateUtil.stringToDate(date));
                        Object[] d = (Object[]) object;
                        BigDecimal highestPrice = (BigDecimal) d[0];
                        BigDecimal lowestPrice = (BigDecimal) d[1];
                        if (highestPrice.compareTo(newestHighestPrice) == -1){
                            highestPrice = newestHighestPrice;
                        }
                        if (lowestPrice.compareTo(newestLowestPrice) == 1){
                            lowestPrice = newestLowestPrice;
                        }
                        BigDecimal closePrice = realTransactionCondition.getKdGoldCrossRsv().divide(new BigDecimal(100)).multiply(highestPrice.subtract(lowestPrice)).add(lowestPrice);
                        if (newestClosePrice.compareTo(closePrice) >= 0) {
                            StockInfoPojo stockInfoPojo = ModelConverter.stockInfoToStockInfoPojo(stockInfo);
                            stockInfoPojo.setAmount(((int) (oneStockTransactionCapitalAmount.intValue() / newestClosePrice.doubleValue()) / 100 * 100));
                            shouldBuyBullStockList.add(stockInfoPojo);
                        }
                    }
                    if (null != realTransactionCondition
                            && null != realTransactionCondition.getKdGoldCrossRsv()
                            && FilterMethod.SELECT_FILTER_METHOD != FilterMethod.KD_GOLD_CROSS) {
                        Object object = stockTransactionDataDao.findHighestAndLowestClosePriceByCodeAndDateInEightDay(stockInfo.getCode(), DateUtil.stringToDate(date));
                        Object[] d = (Object[]) object;
                        BigDecimal highestPrice = (BigDecimal) d[0];
                        BigDecimal lowestPrice = (BigDecimal) d[1];
                        if (highestPrice.compareTo(newestHighestPrice) == -1){
                            highestPrice = newestHighestPrice;
                        }
                        if (lowestPrice.compareTo(newestLowestPrice) == 1){
                            lowestPrice = newestLowestPrice;
                        }
                        BigDecimal closePrice = realTransactionCondition.getKdGoldCrossRsv().divide(new BigDecimal(100)).multiply(highestPrice.subtract(lowestPrice)).add(lowestPrice);
                        if (newestClosePrice.compareTo(closePrice) >= 0) {
                            StockInfoPojo stockInfoPojo = ModelConverter.stockInfoToStockInfoPojo(stockInfo);
                            stockInfoPojo.setAmount(((int) (oneStockTransactionCapitalAmount.intValue() / newestClosePrice.doubleValue()) / 100 * 100));
                            kdGoldCrossShouldBuyStockList.add(stockInfoPojo);
                        }
                    }
                    // kd死叉
                    if (null != realTransactionCondition
                            && null != realTransactionCondition.getKdDeadCrossRsv()
                            && FilterMethod.SELECT_FILTER_METHOD == FilterMethod.KD_DEAD_CROSS
                            && null != stockInfo.getMark()
                            && stockInfo.getMark().equals(StockInfoMark.SECURITIES_LENDING)) {
                        Object object = stockTransactionDataDao.findHighestAndLowestClosePriceByCodeAndDateInEightDay(stockInfo.getCode(), DateUtil.stringToDate(date));
                        Object[] d = (Object[]) object;
                        BigDecimal highestPrice = (BigDecimal) d[0];
                        BigDecimal lowestPrice = (BigDecimal) d[1];
                        if (highestPrice.compareTo(newestHighestPrice) == -1){
                            highestPrice = newestHighestPrice;
                        }
                        if (lowestPrice.compareTo(newestLowestPrice) == 1){
                            lowestPrice = newestLowestPrice;
                        }
                        BigDecimal closePrice = realTransactionCondition.getKdDeadCrossRsv().divide(new BigDecimal(100)).multiply(highestPrice.subtract(lowestPrice)).add(lowestPrice);
                        if (newestClosePrice.compareTo(closePrice) <= 0) {
                            StockInfoPojo stockInfoPojo = ModelConverter.stockInfoToStockInfoPojo(stockInfo);
                            stockInfoPojo.setAmount(((int) (oneStockTransactionCapitalAmount.intValue() / newestClosePrice.doubleValue()) / 100 * 100));
                            shouldSellShortStockList.add(stockInfoPojo);
                        }
                    }
                    if (null != realTransactionCondition
                            && null != realTransactionCondition.getKdDeadCrossRsv()
                            && FilterMethod.SELECT_FILTER_METHOD != FilterMethod.KD_DEAD_CROSS
                            && null != stockInfo.getMark()
                            && stockInfo.getMark().equals(StockInfoMark.SECURITIES_LENDING)) {
                        Object object = stockTransactionDataDao.findHighestAndLowestClosePriceByCodeAndDateInEightDay(stockInfo.getCode(), DateUtil.stringToDate(date));
                        Object[] d = (Object[]) object;
                        BigDecimal highestPrice = (BigDecimal) d[0];
                        BigDecimal lowestPrice = (BigDecimal) d[1];
                        if (highestPrice.compareTo(newestHighestPrice) == -1){
                            highestPrice = newestHighestPrice;
                        }
                        if (lowestPrice.compareTo(newestLowestPrice) == 1){
                            lowestPrice = newestLowestPrice;
                        }
                        BigDecimal closePrice = realTransactionCondition.getKdDeadCrossRsv().divide(new BigDecimal(100)).multiply(highestPrice.subtract(lowestPrice)).add(lowestPrice);
                        if (newestClosePrice.compareTo(closePrice) <= 0) {
                            StockInfoPojo stockInfoPojo = ModelConverter.stockInfoToStockInfoPojo(stockInfo);
                            stockInfoPojo.setAmount(((int) (oneStockTransactionCapitalAmount.intValue() / newestClosePrice.doubleValue()) / 100 * 100));
                            kdDeadCrossShouldSellStockList.add(stockInfoPojo);
                        }
                    }
                }
                bullStockSuggestionList.setShouldBuyBullStockList(shouldBuyBullStockList);
                shortStockSuggestionList.setShouldSellShortStockList(shouldSellShortStockList);
            } else {
                logger.warn("没有买入股票/融券的建议");
            }
        }

        /*********************************** 打印卖出建议和买入建议 *********************************/
        super.printlnAndCollectString(printRealBuySellSuggestion, "-------------------------------------------------------------------------");
        // 打印使用哪种交易策略
//        super.printlnAndCollectString(printRealBuySellSuggestion, transactionStrategyString);
        // 打印最大成功率是否小于阈值
//        super.printlnAndCollectString(printRealBuySellSuggestion, lessThanThresholdMessage);
        // 打印各种算法的成功率/百分比
//        super.printlnAndCollectString(printRealBuySellSuggestion, "MACD金叉算法的成功率/百分比【" + macdGoldCrossSuccessRateValue + "】");
//        super.printlnAndCollectString(printRealBuySellSuggestion, "MACD死叉算法的成功率/百分比【" + macdDeadCrossSuccessRateValue + "】");
//        super.printlnAndCollectString(printRealBuySellSuggestion, "close_price金叉ma5算法的成功率/百分比【" + closePriceMa5GoldCrossSuccessRateValue + "】");
//        super.printlnAndCollectString(printRealBuySellSuggestion, "close_price死叉ma5算法的成功率/百分比【" + closePriceMa5DeadCrossSuccessRateValue + "】");
//        super.printlnAndCollectString(printRealBuySellSuggestion, "hei_kin_ashi上涨趋势算法的成功率/百分比【" + heiKinAshiUpDownSuccessRateValue + "】");
//        super.printlnAndCollectString(printRealBuySellSuggestion, "hei_kin_ashi下跌趋势算法的成功率/百分比【" + heiKinAshiDownUpSuccessRateValue + "】");
//        super.printlnAndCollectString(printRealBuySellSuggestion, "KD金叉算法的成功率/百分比【" + kdGoldCrossSuccessRateValue + "】");
//        super.printlnAndCollectString(printRealBuySellSuggestion, "KD死叉算法的成功率/百分比【" + kdDeadCrossSuccessRateValue + "】");
        super.printlnAndCollectString(printRealBuySellSuggestion, null);
        // 打印应该有的仓位
//        super.printlnAndCollectString(printRealBuySellSuggestion, "应该有的仓位【" + shippingSpace + "】，应该使用的算法为【" + FilterMethod.SELECT_FILTER_METHOD + "】");
        super.printlnAndCollectString(printRealBuySellSuggestion, null);
        // 打印融券/买入股票的建议
        super.printlnAndCollectString(printRealBuySellSuggestion, "应该卖出/还券的股票：");
        if (null != bullStockSuggestionList && null != bullStockSuggestionList.getShouldSellBullStockList()
                && bullStockSuggestionList.getShouldSellBullStockList().size() > 0) {
            for (StockInfoPojo stockInfoPojo : bullStockSuggestionList.getShouldSellBullStockList()) {
                super.printlnAndCollectString(printRealBuySellSuggestion, "之前买入，现在应该卖出的股票：" + stockInfoPojo.getName() + "      " + stockInfoPojo.getCode());
            }
        } else {
            super.printlnAndCollectString(printRealBuySellSuggestion, "没有之前买入，现在应该卖出的股票的建议");
        }
        if (null != shortStockSuggestionList && null != shortStockSuggestionList.getShouldBuyShortStockList()
                && shortStockSuggestionList.getShouldBuyShortStockList().size() > 0) {
            for (StockInfoPojo stockInfoPojo : shortStockSuggestionList.getShouldBuyShortStockList()) {
                super.printlnAndCollectString(printRealBuySellSuggestion, "之前融券，现在应该还券的股票：" + stockInfoPojo.getName() + "      " + stockInfoPojo.getCode());
            }
        } else {
            super.printlnAndCollectString(printRealBuySellSuggestion, "没有之前融券，现在应该还券的股票的建议");
        }
        super.printlnAndCollectString(printRealBuySellSuggestion, null);
        // 计算能买的股票/融券的数量
        Integer canBuyOrSellStockNumber = shippingSpace - (holdBullStockNumberList != null ? holdBullStockNumberList.size() : 0) - (holdShortStockNumberList != null ? holdShortStockNumberList.size() : 0);
        // 打印买入股票/融券的建议
        if (0 == canBuyOrSellStockNumber) {
            super.printlnAndCollectString(printRealBuySellSuggestion, "总共可以买入/融券的股票数量为【" + ((holdBullStockNumberList != null ? holdBullStockNumberList.size() : 0) + (holdShortStockNumberList != null ? holdShortStockNumberList.size() : 0)) + "】");
            super.printlnAndCollectString(printRealBuySellSuggestion, "仓位已满，不需要再买入股票/融券。现在的仓位是【" + shippingSpace + "】");
            super.printlnAndCollectString(printRealBuySellSuggestion, null);
            if (null != bullStockSuggestionList && null != bullStockSuggestionList.getShouldBuyBullStockList()
                    && bullStockSuggestionList.getShouldBuyBullStockList().size() > 0) {
                for (int j = 0; j < bullStockSuggestionList.getShouldBuyBullStockList().size(); j++) {
                    super.printlnAndCollectString(printRealBuySellSuggestion, "原本可以考虑买入的股票：" + bullStockSuggestionList.getShouldBuyBullStockList().get(j).getName() + "  " + bullStockSuggestionList.getShouldBuyBullStockList().get(j).getCode() + "  " + bullStockSuggestionList.getShouldBuyBullStockList().get(j).getAmount());
                }
            }
            if (null != shortStockSuggestionList && null != shortStockSuggestionList.getShouldSellShortStockList()
                    && shortStockSuggestionList.getShouldSellShortStockList().size() > 0) {
                for (int j = 0; j < shortStockSuggestionList.getShouldSellShortStockList().size(); j++) {
                    super.printlnAndCollectString(printRealBuySellSuggestion, "原本可以考虑融券的股票：" + shortStockSuggestionList.getShouldSellShortStockList().get(j).getName() + "  " + shortStockSuggestionList.getShouldSellShortStockList().get(j).getCode() + "  " + shortStockSuggestionList.getShouldSellShortStockList().get(j).getAmount());
                }
            }
        } else {
            if (null != FilterMethod.SELECT_FILTER_METHOD && FilterMethod.SELECT_FILTER_METHOD % 2 == 1 && null != bullStockSuggestionList
                    && null != bullStockSuggestionList.getShouldBuyBullStockList()
                    && bullStockSuggestionList.getShouldBuyBullStockList().size() > 0) {
                super.printlnAndCollectString(printRealBuySellSuggestion, "现在是多头占优势，以买入股票为主");
                super.printlnAndCollectString(printRealBuySellSuggestion, null);
                int otherStockNumber = 0;
                for (int i = 0; i < bullStockSuggestionList.getShouldBuyBullStockList().size() && canBuyOrSellStockNumber > 0; i++, canBuyOrSellStockNumber--) {
                    super.printlnAndCollectString(printRealBuySellSuggestion, "应该买入的股票/融券：" + bullStockSuggestionList.getShouldBuyBullStockList().get(i).getName() + "  " + bullStockSuggestionList.getShouldBuyBullStockList().get(i).getCode() + "  " + bullStockSuggestionList.getShouldBuyBullStockList().get(i).getAmount());
                    otherStockNumber = i + 1;
                }
                super.printlnAndCollectString(printRealBuySellSuggestion, null);
                for (int j = otherStockNumber; j < bullStockSuggestionList.getShouldBuyBullStockList().size(); j++) {
                    super.printlnAndCollectString(printRealBuySellSuggestion, "其余可以考虑买入的股票/融券：" + bullStockSuggestionList.getShouldBuyBullStockList().get(j).getName() + "  " + bullStockSuggestionList.getShouldBuyBullStockList().get(j).getCode() + "  " + bullStockSuggestionList.getShouldBuyBullStockList().get(j).getAmount());
                }
            } else if (null != FilterMethod.SELECT_FILTER_METHOD && FilterMethod.SELECT_FILTER_METHOD % 2 == 0 && null != shortStockSuggestionList
                    && null != shortStockSuggestionList.getShouldSellShortStockList()
                    && shortStockSuggestionList.getShouldSellShortStockList().size() > 0) {
                super.printlnAndCollectString(printRealBuySellSuggestion, "现在是空头占优势，以融券为主");
                super.printlnAndCollectString(printRealBuySellSuggestion, null);
                int otherStockNumber = 0;
                for (int i = 0; i < shortStockSuggestionList.getShouldSellShortStockList().size() && canBuyOrSellStockNumber > 0; i++, canBuyOrSellStockNumber--) {
                    super.printlnAndCollectString(printRealBuySellSuggestion, "应该融券/买入的股票：" + shortStockSuggestionList.getShouldSellShortStockList().get(i).getName() + "  " + shortStockSuggestionList.getShouldSellShortStockList().get(i).getCode() + "  " + shortStockSuggestionList.getShouldSellShortStockList().get(i).getAmount());
                    otherStockNumber = i + 1;
                }
                super.printlnAndCollectString(printRealBuySellSuggestion, null);
                for (int j = otherStockNumber; j < shortStockSuggestionList.getShouldSellShortStockList().size(); j++) {
                    super.printlnAndCollectString(printRealBuySellSuggestion, "其余可以考虑融券/买入的股票：" + shortStockSuggestionList.getShouldSellShortStockList().get(j).getName() + "  " + shortStockSuggestionList.getShouldSellShortStockList().get(j).getCode() + "  " + shortStockSuggestionList.getShouldSellShortStockList().get(j).getAmount());
                }
            } else {
                super.printlnAndCollectString(printRealBuySellSuggestion, "没有买入股票/融券的建议");
            }
        }
        super.printlnAndCollectString(printRealBuySellSuggestion, null);
        // 成功率不是最高的算法，可以考虑买入的股票
        super.printlnAndCollectString(printRealBuySellSuggestion, "成功率不是最高的算法，可以考虑买入的股票/融券：");
        if (null != macdGoldCrossShouldBuyStockList && macdGoldCrossShouldBuyStockList.size() > 0) {
            super.printlnAndCollectString(printRealBuySellSuggestion, "MACD金叉算法，可以考虑买入的股票：");
            for (int i = 0; i < macdGoldCrossShouldBuyStockList.size(); i++) {
                super.printlnAndCollectString(printRealBuySellSuggestion, macdGoldCrossShouldBuyStockList.get(i).getCode() + "    " + macdGoldCrossShouldBuyStockList.get(i).getName() + "    " + macdGoldCrossShouldBuyStockList.get(i).getAmount());
            }
        }
        if (null != macdDeadCrossShouldSellStockList && macdDeadCrossShouldSellStockList.size() > 0) {
            super.printlnAndCollectString(printRealBuySellSuggestion, "MACD死叉算法，可以考虑融券：");
            for (int i = 0; i < macdDeadCrossShouldSellStockList.size(); i++) {
                super.printlnAndCollectString(printRealBuySellSuggestion, macdDeadCrossShouldSellStockList.get(i).getCode() + "    " + macdDeadCrossShouldSellStockList.get(i).getName() + "    " + macdDeadCrossShouldSellStockList.get(i).getAmount());
            }
        }
        if (null != closePriceGoldCrossMa5ShouldBuyStockList && closePriceGoldCrossMa5ShouldBuyStockList.size() > 0) {
            super.printlnAndCollectString(printRealBuySellSuggestion, "close_price金叉ma5算法，可以考虑买入的股票：");
            for (int i = 0; i < closePriceGoldCrossMa5ShouldBuyStockList.size(); i++) {
                super.printlnAndCollectString(printRealBuySellSuggestion, closePriceGoldCrossMa5ShouldBuyStockList.get(i).getCode() + "    " + closePriceGoldCrossMa5ShouldBuyStockList.get(i).getName() + "    " + closePriceGoldCrossMa5ShouldBuyStockList.get(i).getAmount());
            }
        }
        if (null != closePriceDeadCrossMa5ShouldSellStockList && closePriceDeadCrossMa5ShouldSellStockList.size() > 0) {
            super.printlnAndCollectString(printRealBuySellSuggestion, "close_price死叉ma5算法，可以考虑融券：");
            for (int i = 0; i < closePriceDeadCrossMa5ShouldSellStockList.size(); i++) {
                super.printlnAndCollectString(printRealBuySellSuggestion, closePriceDeadCrossMa5ShouldSellStockList.get(i).getCode() + "    " + closePriceDeadCrossMa5ShouldSellStockList.get(i).getName() + "    " + closePriceDeadCrossMa5ShouldSellStockList.get(i).getAmount());
            }
        }
        if (null != heiKinAshiUpDownShouldBuyStockList && heiKinAshiUpDownShouldBuyStockList.size() > 0) {
            super.printlnAndCollectString(printRealBuySellSuggestion, "hei_kin_ashi上涨趋势算法，可以考虑买入的股票：");
            for (int i = 0; i < heiKinAshiUpDownShouldBuyStockList.size(); i++) {
                super.printlnAndCollectString(printRealBuySellSuggestion, heiKinAshiUpDownShouldBuyStockList.get(i).getCode() + "    " + heiKinAshiUpDownShouldBuyStockList.get(i).getName() + "    " + heiKinAshiUpDownShouldBuyStockList.get(i).getAmount());
            }
        }
        if (null != heiKinAshiDownUpShouldSellStockList && heiKinAshiDownUpShouldSellStockList.size() > 0) {
            super.printlnAndCollectString(printRealBuySellSuggestion, "hei_kin_ashi下跌趋势算法，可以考虑融券：");
            for (int i = 0; i < heiKinAshiDownUpShouldSellStockList.size(); i++) {
                super.printlnAndCollectString(printRealBuySellSuggestion, heiKinAshiDownUpShouldSellStockList.get(i).getCode() + "    " + heiKinAshiDownUpShouldSellStockList.get(i).getName() + "    " + heiKinAshiDownUpShouldSellStockList.get(i).getAmount());
            }
        }
        if (null != kdGoldCrossShouldBuyStockList && kdGoldCrossShouldBuyStockList.size() > 0) {
            super.printlnAndCollectString(printRealBuySellSuggestion, "kd金叉算法，可以考虑买入的股票：");
            for (int i = 0; i < kdGoldCrossShouldBuyStockList.size(); i++) {
                super.printlnAndCollectString(printRealBuySellSuggestion, kdGoldCrossShouldBuyStockList.get(i).getCode() + "    " + kdGoldCrossShouldBuyStockList.get(i).getName() + "    " + kdGoldCrossShouldBuyStockList.get(i).getAmount());
            }
        }
        if (null != kdDeadCrossShouldSellStockList && kdDeadCrossShouldSellStockList.size() > 0) {
            super.printlnAndCollectString(printRealBuySellSuggestion, "kd死叉算法，可以考虑融券：");
            for (int i = 0; i < kdDeadCrossShouldSellStockList.size(); i++) {
                super.printlnAndCollectString(printRealBuySellSuggestion, kdDeadCrossShouldSellStockList.get(i).getCode() + "    " + kdDeadCrossShouldSellStockList.get(i).getName() + "    " + kdDeadCrossShouldSellStockList.get(i).getAmount());
            }
        }
        super.printlnAndCollectString(printRealBuySellSuggestion, "-------------------------------------------------------------------------");

        /*********************************** 将买卖建议保存到文件中 *********************************/
        // 保存真实交易的买卖建议
        File file;
        try {
            file = new File(PRINT_REAL_BUY_SELL_SUGGESTION);
            if (!file.exists()) {
                file.createNewFile();
            }
            FileWriter writer = new FileWriter(file);
            writer.write(printRealBuySellSuggestion.toString());
            writer.flush();
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        logger.info("实时地判断买卖条件，给出交易建议，并保存在文件中完成");
    }

    @Override
    public String listToString(List list) {
        return null;
    }


}
